home *** CD-ROM | disk | FTP | other *** search
- /********************************************************************
- *
- * File: MakePath.c
- * Description: Main code module for MakePath
- * Author: Ole Martin Bjørndalen (olemb@stud.cs.uit.no)
- * Version: 1.1a
- * Status: Public domain
- * Last changed: 27 Sep 1997
- *
- ********************************************************************/
-
- #define __USE_SYSBASE
-
- #include <proto/dos.h>
- #include <proto/exec.h>
- #include <exec/memory.h>
-
- #include <string.h>
-
- /* Uncomment the next line to activate debugging */
- //#define DEBUG 1
- #include "debug.h"
-
- UBYTE fver[] = "$VER: MakePath 1.1a " __AMIGADATE__ " Ole Martin Bjørndalen";
-
- /****** CliTools/MakePath *******************************************
- *
- * NAME
- * MakePath -- Creates or completes path.
- *
- * TEMPLATE
- * PATH/M/A
- *
- * FUNCTION
- * MakePath attempts to create or complete the path you
- * specify. Directories that do not exist will be created.
- * If MakePath returns without errors, the full path is
- * guaranteed to be there.
- *
- * MakePath does not create icons for the new drawers.
- *
- * ARGUMENTS
- * PATH - One or more paths to create
- *
- * RESULT
- * Returns FAIL if something went wrong, else OK.
- *
- * EXAMPLES
- * MakePath a/short/path
- * MakePath a/path another/path
- * MakePath this//is//perfectly//legal
- *
- * NOTES
- * Unlike MakeDir, MakePath will not fail if a directory
- * already exists. You may want to know this when writing
- * scripts.
- *
- * BUGS
- * None known
- *
- * AUTHOR
- * Ole Martin Bjørndalen (olemb@stud.cs.uit.no)
- *
- * SEE ALSO
- * C:MakeDir
- *
- *****************************************************************************
- *
- */
-
- BOOL MakePath(struct ExecBase *SysBase,
- struct DosLibrary *DOSBase,
- STRPTR path);
-
- /*
- Define an argument structure for ReadArgs().
- If find this is more readable than using a
- LONG array, even for one argument
- */
- struct Arguments {
- STRPTR *path;
- };
-
- #define TEMPLATE "PATH/M/A"
-
- /*
- There is no startup code, so we'll have to do
- all the setup ourselves. Most of the work is done
- by dos.library, though.
- */
- int startup(void)
- {
- LONG result = RETURN_OK;
- struct ExecBase *SysBase;
- struct Process *proc;
-
- SysBase = (*((struct ExecBase **) 4));
- proc = (struct Process *)FindTask(NULL);
-
- /*
- Make sure we don't crash if started from WB
- */
- if(proc->pr_CLI)
- {
- struct DosLibrary *DOSBase;
-
- if(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 36L))
- {
- struct RDArgs *rdargs;
- struct Arguments args = { NULL };
-
- if(rdargs = ReadArgs(TEMPLATE, (LONG *)&args, NULL))
- {
- int i;
-
- for(i = 0; args.path[i]; i++)
- {
- if(!MakePath(SysBase, DOSBase, args.path[i]))
- {
- /* Failed! Let's get outta here! */
- result = RETURN_FAIL;
- break;
- }
- }
- }
- else
- {
- PrintFault(IoErr(), NULL);
- result = RETURN_FAIL;
- }
-
- CloseLibrary((struct Library *)DOSBase);
- }
- else
- {
- proc->pr_Result2 = ERROR_INVALID_RESIDENT_LIBRARY;
- }
- }
- else
- {
- /*
- Started from WB. Reply startup
- message and exit gracefully
- */
- struct Message *msg;
-
- WaitPort(&proc->pr_MsgPort);
-
- if(msg = GetMsg(&proc->pr_MsgPort))
- {
- Forbid();
- ReplyMsg(msg);
- }
- }
-
- return result;
- }
-
- /*
- Create the actual path. If this fails, an
- error code is printed and FALSE is returned.
-
- I use SetIoErr() because it allows me to
- use PrintFault() for my own error conditions.
- Thus, MakePath is fully localized.
- */
- BOOL MakePath(struct ExecBase *SysBase,
- struct DosLibrary *DOSBase,
- STRPTR path)
- {
- BOOL success = FALSE;
- UBYTE *buffer;
-
- D(bug("MakePath(%s)\n", path));
-
- /* Allocate a temporary buffer to hold the path */
- if(buffer = AllocVec(strlen(path) + 1, MEMF_ANY))
- {
- LONG p;
-
- // D(bug("Buffer allocated\n"));
-
- /*
- Iterate through the buffer and stop
- between path components
- */
- for(p = 0; ;p++)
- {
- if(path[p] == '/' || path[p] == '\0')
- {
- BPTR lock;
-
- /*
- Temporary NULL termination
- */
- buffer[p] = '\0';
-
- D(bug("Lock(%s)\n", buffer));
-
- /*
- Expect the worst. This will be
- set back to TRUE if all went well
- */
- success = FALSE;
-
- /* Does the directory exist? */
- if(lock = Lock(buffer, ACCESS_READ))
- {
- __aligned struct FileInfoBlock fib;
-
- D(bug("Examine(%s)\n", buffer));
-
- /* Yes, but is it really a directory? */
- if(Examine(lock, &fib))
- {
- if(fib.fib_DirEntryType > 0)
- {
- success = TRUE;
- }
- else
- {
- /* fail */
- SetIoErr(ERROR_OBJECT_WRONG_TYPE);
- }
- }
- /* else fail */
- }
- else
- {
- /*
- If I didn't test this, the
- "please insert volume X"
- requester would open twice.
- Also, if a serious error has
- occured, calling CreateDir()
- is rather pointless.
- */
- if(IoErr() == ERROR_OBJECT_NOT_FOUND)
- {
- D(bug("CreateDir(%s)\n", buffer));
-
- if(lock = CreateDir(buffer))
- {
- success = TRUE;
- }
- else
- {
- /* fail */
- D(bug("CreateDir() failed!\n"));
- }
- }
- /* else fail */
-
- } /* Lock() */
-
- if(lock)
- UnLock(lock);
-
- if(!success)
- {
- /*
- An error occured.
- Inform user and bail out
- */
- PrintFault(IoErr(), buffer);
- break;
- }
-
- if(path[p] == '\0')
- {
- /* Reached the end of the string */
- break;
- }
-
- } /* if('/' || '\0') */
-
- /* Copy character to work buffer */
- buffer[p] = path[p];
-
- } /* for() */
- }
- else
- {
- PrintFault(ERROR_NO_FREE_STORE, NULL);
- }
-
- D(bug("%s\n", success ? "SUCCESS" : "FAILURE"));
-
- return success;
- }
-